package me.buick.util.snmp.core.dao.impl.snmp;

import java.io.IOException;

import me.buick.util.snmp.core.AbstractPerfDAOFactory;
import me.buick.util.snmp.core.SupportedOS;
import me.buick.util.snmp.core.dao.DiskInfoDAO;
import me.buick.util.snmp.core.dao.NetworkIfInfoDAO;
import me.buick.util.snmp.core.dao.ProcessInfoDAO;
import me.buick.util.snmp.core.dao.SystemInfoDAO;

import org.opengoss.snmphibernate.api.ISnmpClientFacade;
import org.opengoss.snmphibernate.api.ISnmpSession;
import org.opengoss.snmphibernate.api.ISnmpSessionFactory;
import org.opengoss.snmphibernate.api.ISnmpTargetFactory;
import org.opengoss.snmphibernate.impl.snmp4j.Snmp4JClientFacade;


/**
 * 
 * Version 1.0
 * 
 * @author buick
 */
public class SNMPPerfDAOFactory extends AbstractPerfDAOFactory {

	private ISnmpSession 	session;
	private SupportedOS  	os;
	private String 		 	host;
	private int    		 	port;
	private long 		 	interval;
	private SNMPDataPoller  snmpDataPoller;
	
	private SNMPDiskInfoDAO diskInfoDAO = null;
	private SNMPNetworkInfoDAO networkIfInfoDAO = null;
	private SNMPProcessInfoDAO processInfoDAO = null;
	private SNMPSystemInfoDAO systemInfoDAO = null;	
	
	/** 
	 * This construtor creates a ConcreteProduct instance.
	 */
	public SNMPPerfDAOFactory(SupportedOS os, String host, int port, long interval) {
		super();
		this.host 	  = host;
		this.port 	  = port;
		this.os   	  = os;
		this.interval = interval;
	
			try {
			    ISnmpClientFacade facade = new Snmp4JClientFacade();
			    ISnmpSessionFactory sessionFactory = facade.getSnmpSessionFactory();
			    ISnmpTargetFactory targetFactory = facade.getSnmpTargetFactory();   
			    session = sessionFactory.newSnmpSession(targetFactory.newSnmpTarget(this.host, this.port));
			}catch(Exception e){
				throw new InstantiationError("Error when instantiating PerfDAOSNMPImpl!, root cause: " + e.getLocalizedMessage());
			}
		
		if(interval > 0){
			snmpDataPoller = new SNMPDataPoller(this.interval);
			snmpDataPoller.start();
		}
	}

	@Override
	public DiskInfoDAO getDiskInfoDAO() {
		
		if(interval > 0){
			
			if(this.diskInfoDAO == null)
			{
				this.diskInfoDAO = new SNMPDiskInfoDAO(this.os, session);
				snmpDataPoller.add(diskInfoDAO);
			}
			return diskInfoDAO;
		
		}else{
			return new SNMPDiskInfoDAO(this.os, session);
		}
	}

	@Override
	public NetworkIfInfoDAO getNetworkIfInfoDAO() {
	
		if(interval > 0 ){

			if(this.networkIfInfoDAO == null)
			{
				this.networkIfInfoDAO = new SNMPNetworkInfoDAO(this.os, session);
				snmpDataPoller.add(networkIfInfoDAO);
			}
			return networkIfInfoDAO;

			
		}else{
			return new SNMPNetworkInfoDAO(this.os, session);
		}
	}

	@Override
	public SystemInfoDAO getSystemInfoDAO() {
		if(interval > 0 ){

			if(this.systemInfoDAO == null)
			{
				this.systemInfoDAO = new SNMPSystemInfoDAO(this.os, session);
				snmpDataPoller.add(systemInfoDAO);
			}
			return systemInfoDAO;

			
		}else{
			return new SNMPSystemInfoDAO(this.os, session);
		}
	}
	
	@Override
	public ProcessInfoDAO getProcessInfoDAO() {
		if(interval > 0 ){

			if(this.processInfoDAO == null)
			{
				this.processInfoDAO = new SNMPProcessInfoDAO(this.os, session);
				snmpDataPoller.add(processInfoDAO);
			}
			return processInfoDAO;

			
		}else{
			return new SNMPProcessInfoDAO(this.os, session);
		}
	}

	@Override
	public boolean discardDAOs() {
		try {
			this.session.close();
			if(this.snmpDataPoller != null){
				this.snmpDataPoller.stop();
			}
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
}
